From b726f60f9039b647d6c6b7fe4f417923d65140a2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Sun, 4 Feb 2018 22:24:44 +0100 Subject: [PATCH] searchbar: reorganize Avoid the ugly priv->tool_box==NULL check in ::add (and ::remove) by just not using template xml for this small class. Also, make sure the GtkBin child is properly set and implement remove to also properly remove it. Remove the manual widget margins and add some CSS for it. Also switch to simply using a GtkCenterBox. --- gtk/gtksearchbar.c | 142 ++++++++++++++--------- gtk/theme/Adwaita/_common.scss | 7 ++ gtk/theme/Adwaita/gtk-contained-dark.css | 2 + gtk/theme/Adwaita/gtk-contained.css | 2 + gtk/ui/gtksearchbar.ui | 41 ------- 5 files changed, 96 insertions(+), 98 deletions(-) delete mode 100644 gtk/ui/gtksearchbar.ui diff --git a/gtk/gtksearchbar.c b/gtk/gtksearchbar.c index acd85995c9..169861f23f 100644 --- a/gtk/gtksearchbar.c +++ b/gtk/gtksearchbar.c @@ -28,6 +28,9 @@ #include "config.h" #include "gtkentry.h" +#include "gtkbox.h" +#include "gtkcenterbox.h" +#include "gtkbutton.h" #include "gtkentryprivate.h" #include "gtkintl.h" #include "gtkprivate.h" @@ -58,7 +61,18 @@ * * # CSS nodes * - * GtkSearchBar has a single CSS node with name searchbar. + * |[ + * searchbar + * ╰── revealer + * ╰── box + * ├── [child] + * ╰── [button.close] + * ]| + * + * GtkSearchBar has a main CSS node with name searchbar. It has a child node + * with name revealer that contains a node with name box. The box node contains both the + * CSS node of the child widget as well as an optional button node which gets the .close + * style class applied. * * ## Creating a search bar * @@ -68,9 +82,7 @@ */ typedef struct { - /* Template widgets */ GtkWidget *revealer; - GtkWidget *tool_box; GtkWidget *box_center; GtkWidget *close_button; @@ -252,8 +264,6 @@ reveal_child_changed_cb (GObject *object, gboolean reveal_child; g_object_get (object, "reveal-child", &reveal_child, NULL); - if (reveal_child) - gtk_widget_set_child_visible (priv->revealer, TRUE); if (reveal_child == priv->reveal_child) return; @@ -271,19 +281,6 @@ reveal_child_changed_cb (GObject *object, g_object_notify (G_OBJECT (bar), "search-mode-enabled"); } -static void -child_revealed_changed_cb (GObject *object, - GParamSpec *pspec, - GtkSearchBar *bar) -{ - GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); - gboolean val; - - g_object_get (object, "child-revealed", &val, NULL); - if (!val) - gtk_widget_set_child_visible (priv->revealer, FALSE); -} - static void close_button_clicked_cb (GtkWidget *button, GtkSearchBar *bar) @@ -300,24 +297,14 @@ gtk_search_bar_add (GtkContainer *container, GtkSearchBar *bar = GTK_SEARCH_BAR (container); GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); - /* When constructing the widget, we want the revealer to be added - * as the first child of the search bar, as an implementation detail. - * After that, the child added by the application should be added - * to box_center. + gtk_center_box_set_center_widget (GTK_CENTER_BOX (priv->box_center), child); + /* If an entry is the only child, save the developer a couple of + * lines of code */ - if (priv->box_center == NULL) - { - GTK_CONTAINER_CLASS (gtk_search_bar_parent_class)->add (container, child); - } - else - { - gtk_container_add (GTK_CONTAINER (priv->box_center), child); - /* If an entry is the only child, save the developer a couple of - * lines of code - */ - if (GTK_IS_ENTRY (child)) - gtk_search_bar_connect_entry (bar, GTK_ENTRY (child)); - } + if (GTK_IS_ENTRY (child)) + gtk_search_bar_connect_entry (bar, GTK_ENTRY (child)); + + _gtk_bin_set_child (GTK_BIN (container), child); } static void @@ -327,14 +314,11 @@ gtk_search_bar_remove (GtkContainer *container, GtkSearchBar *bar = GTK_SEARCH_BAR (container); GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); - if (priv->box_center == NULL) - { - GTK_CONTAINER_CLASS (gtk_search_bar_parent_class)->remove (container, child); - } - else - { - gtk_container_remove (GTK_CONTAINER (priv->box_center), child); - } + if (GTK_IS_ENTRY (child)) + gtk_search_bar_connect_entry (bar, NULL); + + gtk_center_box_set_center_widget (GTK_CENTER_BOX (priv->box_center), NULL); + _gtk_bin_set_child (GTK_BIN (container), NULL); } static void @@ -389,12 +373,52 @@ static void gtk_search_bar_dispose (GObject *object) { GtkSearchBar *bar = GTK_SEARCH_BAR (object); + GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); + + if (gtk_bin_get_child (GTK_BIN (bar)) != NULL) + { + gtk_center_box_set_center_widget (GTK_CENTER_BOX (priv->box_center), NULL); + _gtk_bin_set_child (GTK_BIN (bar), NULL); + } + + if (priv->revealer != NULL) + { + gtk_widget_unparent (priv->revealer); + priv->revealer = NULL; + } gtk_search_bar_set_entry (bar, NULL); G_OBJECT_CLASS (gtk_search_bar_parent_class)->dispose (object); } +static void +gtk_search_bar_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + GtkSearchBar *bar = GTK_SEARCH_BAR (widget); + GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); + + gtk_widget_measure (priv->revealer, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); +} + +static void +gtk_search_bar_size_allocate (GtkWidget *widget, + const GtkAllocation *allocation, + int baseline, + GtkAllocation *out_clip) +{ + GtkSearchBar *bar = GTK_SEARCH_BAR (widget); + GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); + + gtk_widget_size_allocate (priv->revealer, allocation, baseline, out_clip); +} + static void gtk_search_bar_class_init (GtkSearchBarClass *klass) { @@ -406,6 +430,9 @@ gtk_search_bar_class_init (GtkSearchBarClass *klass) object_class->set_property = gtk_search_bar_set_property; object_class->get_property = gtk_search_bar_get_property; + widget_class->measure = gtk_search_bar_measure; + widget_class->size_allocate = gtk_search_bar_size_allocate; + container_class->add = gtk_search_bar_add; container_class->remove = gtk_search_bar_remove; @@ -435,12 +462,6 @@ gtk_search_bar_class_init (GtkSearchBarClass *klass) g_object_class_install_properties (object_class, LAST_PROPERTY, widget_props); - gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtksearchbar.ui"); - gtk_widget_class_bind_template_child_private (widget_class, GtkSearchBar, tool_box); - gtk_widget_class_bind_template_child_private (widget_class, GtkSearchBar, revealer); - gtk_widget_class_bind_template_child_private (widget_class, GtkSearchBar, box_center); - gtk_widget_class_bind_template_child_private (widget_class, GtkSearchBar, close_button); - gtk_widget_class_set_css_name (widget_class, I_("searchbar")); } @@ -449,21 +470,28 @@ gtk_search_bar_init (GtkSearchBar *bar) { GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar); - gtk_widget_init_template (GTK_WIDGET (bar)); + priv->revealer = gtk_revealer_new (); + gtk_revealer_set_reveal_child (GTK_REVEALER (priv->revealer), FALSE); + gtk_widget_set_hexpand (priv->revealer, TRUE); + gtk_widget_set_parent (priv->revealer, GTK_WIDGET (bar)); + + priv->box_center = gtk_center_box_new (); + gtk_widget_set_hexpand (priv->box_center, TRUE); + + priv->close_button = gtk_button_new_from_icon_name ("window-close-symbolic"); + gtk_style_context_add_class (gtk_widget_get_style_context (priv->close_button), "close"); + gtk_center_box_set_end_widget (GTK_CENTER_BOX (priv->box_center), priv->close_button); + gtk_widget_hide (priv->close_button); + + gtk_container_add (GTK_CONTAINER (priv->revealer), priv->box_center); - /* We use child-visible to avoid the unexpanded revealer - * peaking out by 1 pixel - */ - gtk_widget_set_child_visible (priv->revealer, FALSE); g_signal_connect (priv->revealer, "notify::reveal-child", G_CALLBACK (reveal_child_changed_cb), bar); - g_signal_connect (priv->revealer, "notify::child-revealed", - G_CALLBACK (child_revealed_changed_cb), bar); g_signal_connect (priv->close_button, "clicked", G_CALLBACK (close_button_clicked_cb), bar); -}; +} /** * gtk_search_bar_new: diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss index f42c09e77f..f3d479f64f 100644 --- a/gtk/theme/Adwaita/_common.scss +++ b/gtk/theme/Adwaita/_common.scss @@ -1404,6 +1404,13 @@ searchbar, padding: 0px; } +searchbar { + padding: 0px; + >revealer>box { + padding: 6px; + } +} + %darkbar { border-style: solid; border-color: $borders_color; diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css index cb5ea28dbd..d2552a9a60 100644 --- a/gtk/theme/Adwaita/gtk-contained-dark.css +++ b/gtk/theme/Adwaita/gtk-contained-dark.css @@ -585,6 +585,8 @@ toolbar:not(.inline-toolbar):not(.osd) switch, toolbar:not(.inline-toolbar):not( searchbar, .location-bar { border-width: 0 0 1px; padding: 0px; } +searchbar > revealer > box { padding: 6px; } + .inline-toolbar, searchbar, .location-bar { border-style: solid; border-color: #1b1f20; background-color: #2c3133; } .inline-toolbar:backdrop, searchbar:backdrop, .location-bar:backdrop { border-color: #202425; background-color: #2c3233; box-shadow: none; transition: 200ms ease-out; } diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css index b868e556d1..2f29e88149 100644 --- a/gtk/theme/Adwaita/gtk-contained.css +++ b/gtk/theme/Adwaita/gtk-contained.css @@ -593,6 +593,8 @@ toolbar:not(.inline-toolbar):not(.osd) switch, toolbar:not(.inline-toolbar):not( searchbar, .location-bar { border-width: 0 0 1px; padding: 0px; } +searchbar > revealer > box { padding: 6px; } + .inline-toolbar, searchbar, .location-bar { border-style: solid; border-color: #b6b6b3; background-color: #d9d9d7; } .inline-toolbar:backdrop, searchbar:backdrop, .location-bar:backdrop { border-color: #c0c0bd; background-color: #dadad8; box-shadow: none; transition: 200ms ease-out; } diff --git a/gtk/ui/gtksearchbar.ui b/gtk/ui/gtksearchbar.ui deleted file mode 100644 index d389cf4b4f..0000000000 --- a/gtk/ui/gtksearchbar.ui +++ /dev/null @@ -1,41 +0,0 @@ - - - - - -- 2.30.2